package com.ucode.springboot.starter.web.config;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.validation.Validator;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.hibernate.validator.spi.resourceloading.ResourceBundleLocator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

/**
 * 参数校验配置
 * @author: liliang
 * @date: 2019年12月18日 上午10:49:54
 */
@Configuration
public class ValidatorConfiguration {

//	@Autowired
//	ResourceBundleMessageSource messageSource;
	
	/**
	 * 方法验证处理器
	 * 如果参数校验有异常，直接抛异常，不会进入到 controller，使用全局异常拦截进行拦截
	 * 待验证:spring cloud的项目中,系统启动时，如果有声明MethodValidationPostProcessor的@Bean，则不会去加载自己定义的拦截器；如果未声明MethodValidationPostProcessor的@Bean，系统会寻找自定义的拦截器
	 * @author liliang
	 * @date 2019年12月18日
	 * @return
	 */
	@Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
        postProcessor.setValidator(validator());
        return postProcessor;
    }

	/**
	 * 校验器
	 * @author liliang
	 * @date 2019年12月19日
	 * @return
	 */
    @Bean
    public Validator validator(){
    	LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
//    	new PlatformResourceBundleLocator("i18n/messages_validate" )这里完成massage的国际化
    	validator.setMessageInterpolator(new MessageInterpolator());
    	return validator;
    }
    
    private class MessageInterpolator extends ResourceBundleMessageInterpolator {
        
        MessageInterpolator(){
    	}
    	
    	MessageInterpolator(ResourceBundleLocator resourceBundleLocator){
    		super(resourceBundleLocator);
    	}

    	@Override
    	public String interpolate(String message, Context context, Locale locale) {
    		// 获取注解类型
    		String annotationTypeName = context.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName();
    		
    		// 根据注解类型获取自定义的消息Code
    		String annotationDefaultMessageCode = VALIDATION_ANNATATION_DEFAULT_MESSAGES.get(annotationTypeName);
    		if (null != annotationDefaultMessageCode && !message.startsWith("javax.validation")
    				&& !message.startsWith("org.hibernate.validator.constraints")) {
    			// 如果注解上指定的message不是默认的javax.validation或者org.hibernate.validator等开头的情况，
    			// 则需要将自定义的消息Code拼装到原message的后面；
    			message += "{" + annotationDefaultMessageCode + "}";
    		}
    		
    		return super.interpolate(message, context, locale);
    	}
    }
    
    private static final Map<String, String> VALIDATION_ANNATATION_DEFAULT_MESSAGES =
    		new HashMap<String, String>(20) {{
    			put("CheckCase", "demo.validation.constraints.CheckCase.LOWER.message");
                put("NotNull", "demo.validation.constraints.NotNull.message");
    		}};
    
}